﻿var resultsArray;

var context = Xrm.Page.context;
var serverUrl = context.getServerUrl();
if (serverUrl.match(/\/$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}

function DisplayMap() {

    //Get the fetchXml from the advanced find window.
    var fetchXml = advFind.FetchXml;
    //Create a new XML doc.
    var fetchXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    fetchXmlDoc.async = "false";
    fetchXmlDoc.loadXML(fetchXml);
    //Clear out the existing attribute nodes, we want all attributes
    var attribs = fetchXmlDoc.getElementsByTagName("attribute");
    for (var i = 0; i < attribs.length; i++)
        attribs[i].parentNode.removeChild(attribs[i]);

    //Add the all-attributes element if it isn't there
    var existingAllAttribs = fetchXmlDoc.getElementsByTagName("all-attributes");
    if (existingAllAttribs == null || existingAllAttribs.length == 0) {
        var entityElem = fetchXmlDoc.getElementsByTagName("entity")[0];
        var allAttribElem = fetchXmlDoc.createElement("all-attributes");
        entityElem.insertBefore(allAttribElem, entityElem.childNodes[0]);
    }

    //Get the results from the crm service
    var results = FetchResultsXml(fetchXmlDoc.xml);
    //Process the results from the fetch into an array
    resultsArray = GetArrayFromFetchResults(results, fetchXmlDoc);
    //Open the map webresource
    var mapWindow = window.open(serverUrl + "/WebResources/boggle_BingMapsControl.htm", "mapWindow", "toolbar=0,menubar=0,directories=0,scrollbars=1");
}

function GetArrayFromFetchResults(fetchResults, fetchXmlDoc) {
    //Load the mappings from the mappings web resource
    var entityName = GetEntityNameFromFetch(fetchXmlDoc);
    var mapping = GetMappings(entityName);

    //Instantiate a new array
    var entityResults = new Array();
    //Get all the entity elements
    var entityElems = fetchResults.getElementsByTagName("a:Entity");
    for (var i = 0; i < entityElems.length; i++) {
        //Create a new array object to load the results into
        entityResults[i] = new Object();
        //Get the field values for the object
        entityResults[i].Type = entityName;
        entityResults[i].Id = GetFieldValue(entityElems[i], mapping.Id);
        entityResults[i].Name = GetFieldValue(entityElems[i], mapping.Name);
        if (mapping.Latitude != null && mapping.Longitude != null) {
            entityResults[i].Latitude = GetFieldValue(entityElems[i], mapping.Latitude);
            entityResults[i].Longitude = GetFieldValue(entityElems[i], mapping.Longitude);
        }
        if(mapping.Street != null)
            entityResults[i].Street = GetFieldValue(entityElems[i], mapping.Street);

        if(mapping.City != null)
            entityResults[i].City = GetFieldValue(entityElems[i], mapping.City);

        if (mapping.State != null)
            entityResults[i].State = GetFieldValue(entityElems[i], mapping.State);

        if(mapping.Country != null)
            entityResults[i].Country = GetFieldValue(entityElems[i], mapping.Country);

        if (mapping.Shape != null)
            entityResults[i].Shape = GetFieldValue(entityElems[i], mapping.Shape);
    }
    //Return the array
    return entityResults;
}

function GetFieldValue(entity, fieldName) {
    var vals = entity.getElementsByTagName("a:KeyValuePairOfstringanyType");
    //Find the field that matches the name
    for (var j = 0; j < vals.length; j++) {
        if (vals[j].getElementsByTagName("b:key")[0].firstChild.nodeValue == fieldName) {
            if (vals[j].getElementsByTagName("b:value").length > 0)
                return vals[j].getElementsByTagName("b:value")[0].firstChild.nodeValue;
            else
                return "";
        }
    }
}

function EncodeXml(xml) {
    return xml.replace(/\&/g, '&' + 'amp;').replace(/</g, '&' + 'lt;')
        .replace(/>/g, '&' + 'gt;').replace(/\'/g, '&' + 'apos;').replace(/\"/g, '&' + 'quot;');
}

function FetchResultsXml(fetchXml) {
    //Create the fetch Xml request
    var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
            "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
            "<soapenv:Body>" +
            "<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
            "<query i:type=\"a:FetchExpression\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">" +
            "<a:Query>" + EncodeXml(fetchXml) + "</a:Query>" +
            "</query>" +
            "</RetrieveMultiple>" +
            "</soapenv:Body>" +
            "</soapenv:Envelope>";

    var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    xmlHttpRequest.Open("POST", serverUrl + "/XRMServices/2011/Organization.svc/web", false);
    xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/RetrieveMultiple");
    xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    xmlHttpRequest.setRequestHeader("Content-Length", xml.length);

    //Send the request to CRM
    xmlHttpRequest.send(xml);
    //Load the results into the xml var
    var resultXml = xmlHttpRequest.responseXML;
    return resultXml;
}

function MappingAvailable(entityType) {
    //Load the xml mapping data
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", serverUrl + "/WebResources/boggle_EntityAddressMapping.xml", false);
    xmlhttp.send();
    var dataXmlDoc = xmlhttp.responseXML;

    var mappings = dataXmlDoc.getElementsByTagName("Entity");
    var mappingFound = false;
    if (mappings != null) {
        for (var i = 0; i < mappings.length; i++) {
            if (mappings[i].getAttribute("id") == entityType) {
                mappingFound = true;
                break;
            }
        }
    }
    return mappingFound;
}

function MapAvailable() {
    //Get the fetchXml from the advanced find window.
    var fetchXml = advFind.FetchXml;
    //Create a new XML doc.
    var fetchXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    fetchXmlDoc.async = "false";
    fetchXmlDoc.loadXML(fetchXml);

    var entityName = GetEntityNameFromFetch(fetchXmlDoc);

    return MappingAvailable(entityName);
}

function GetEntityNameFromFetch(fetchXml) {
    var entityElems = fetchXml.getElementsByTagName("entity");

    return entityElems[0].getAttribute("name");
}

function GetMappings(entityName) {
    var mapping = new Object();

    //Load the xml mapping data
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", serverUrl + "/WebResources/boggle_EntityAddressMapping.xml", false);
    xmlhttp.send();
    var dataXmlDoc = xmlhttp.responseXML;

    var mappings = dataXmlDoc.getElementsByTagName("Entity");
    var mappingFound = false;
    if (mappings != null) {
        for (var i = 0; i < mappings.length; i++) {
            if (mappings[i].getAttribute("id") == entityName) {
                var idElem = mappings[i].getElementsByTagName("Id");
                mapping.Id = idElem[0].childNodes[0].nodeValue;

                var nameElem = mappings[i].getElementsByTagName("Name");
                if (nameElem != null && nameElem.length == 1)
                    mapping.Name = nameElem[0].childNodes[0].nodeValue;
                else
                    mapping.Name = null;

                var streetElem = mappings[i].getElementsByTagName("Street");
                if (streetElem != null && streetElem.length == 1)
                    mapping.Street = streetElem[0].childNodes[0].nodeValue;
                else
                    mapping.Street = null;

                var cityElem = mappings[i].getElementsByTagName("City");
                if (cityElem != null && cityElem.length == 1)
                    mapping.City = cityElem[0].childNodes[0].nodeValue;
                else
                    mapping.City = null;

                var stateElem = mappings[i].getElementsByTagName("State");
                if (stateElem != null && stateElem.length == 1)
                    mapping.State = stateElem[0].childNodes[0].nodeValue;
                else
                    mapping.State = null;

                var countryElem = mappings[i].getElementsByTagName("Country");
                if (countryElem != null && countryElem.length == 1)
                    mapping.Country = countryElem[0].childNodes[0].nodeValue;
                else
                    mapping.Country = null;

                var latitudeElem = mappings[i].getElementsByTagName("Latitude");
                if (latitudeElem != null && latitudeElem.length == 1)
                    mapping.Latitude = latitudeElem[0].childNodes[0].nodeValue;
                else
                    mapping.Latitude = null;

                var longitudeElem = mappings[i].getElementsByTagName("Longitude");
                if (longitudeElem != null && longitudeElem.length == 1)
                    mapping.Longitude = longitudeElem[0].childNodes[0].nodeValue;
                else
                    mapping.Longitude = null;

                var shapeElem = mappings[i].getElementsByTagName("Shape");
                if (shapeElem != null && shapeElem.length == 1)
                    mapping.Shape = shapeElem[0].childNodes[0].nodeValue;
                else
                    mapping.Shape = null;

                mappingFound = true;
                break;
            }
        }
        if (mappingFound == false) {
            mapping.Name = null;
            mapping.Street = null;
            mapping.City = null;
            mapping.State = null;
            mapping.Country = null;
            mapping.Latitude = null;
            mapping.Longitude = null;
        }

        return mapping;
    }
}